package com.dmitriyp.movie.view;

import java.util.List;

import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import com.dmitriyp.movie.PluginResources;
import com.dmitriyp.movie.mapping.Movie;

public class MovieListPart {

	private static final String SEARCH_LABEL = "view.label.search";//$NON-NLS-1$
	private static final String SEARCH_BUTTON_TEXT = "view.button.search";//$NON-NLS-1$
	private static final String SEARCH_BY_TITLE = "search.by.title";//$NON-NLS-1$
	private static final String SEARCH_BY_STAR = "search.by.star";//$NON-NLS-1$

	private ListViewer list;
	private Text searchText;
	private Combo searchCriteria;
	/**
	 * empty listener to avoid NullPointerException
	 */
	private IMoviePartListener moviePartListener = new IMoviePartListener() {

		@Override
		public void selected(Movie movie) {}

		@Override
		public void searchByStar(String star) {}

		@Override
		public void searchByTitle(String title) {}

	};
	
	private SelectionListener searchButtonListener = new SelectionAdapter() {
		
		public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
			if(searchCriteria.getSelectionIndex() == 0) {
				moviePartListener.searchByTitle(searchText.getText());
			} else {
				moviePartListener.searchByStar(searchText.getText());
			}
		};
	};

	public MovieListPart(Composite parent) {
		this.createSearchArea(parent);
		this.createList(parent);
	}

	private void createSearchArea(Composite parent) {
		Composite searchComposite = new Composite(parent, 0);
		searchComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false));
		searchComposite.setLayout(new GridLayout(3, false));

		Label label = new Label(searchComposite, 0);
		label.setText(PluginResources.getString(SEARCH_LABEL));

		searchText = new Text(searchComposite, SWT.BORDER
				| SWT.SHADOW_NONE);
		searchText
				.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		searchText.setSize(SWT.DEFAULT, 40);

		Button btn = new Button(searchComposite, SWT.NONE);
		btn.setText(PluginResources.getString(SEARCH_BUTTON_TEXT));
		btn.addSelectionListener(searchButtonListener);

		searchCriteria = new Combo(parent, SWT.SINGLE | SWT.READ_ONLY);
		searchCriteria.setItems(new String[] {
				PluginResources.getString(SEARCH_BY_TITLE),
				PluginResources.getString(SEARCH_BY_STAR) });
		searchCriteria.select(0);
	}

	private void createList(Composite parent) {
		list = new ListViewer(parent);
		list.getControl().setLayoutData(
				new GridData(SWT.FILL, SWT.FILL, true, true));
		list.setContentProvider(new IStructuredContentProvider() {

			@Override
			public void inputChanged(Viewer viewer, Object oldInput,
					Object newInput) {
			}

			@Override
			public void dispose() {
			}

			@SuppressWarnings("unchecked")
			@Override
			public Object[] getElements(Object inputElement) {
				return ((List<Movie>) inputElement).toArray();
			}
		});
		list.setLabelProvider(new LabelProvider() {
			@Override
			public String getText(Object element) {
				Movie m = (Movie) element;
				return m.getTitle() + " - " + m.getReleaseYear();
			}
		});
		list.addSelectionChangedListener(new ISelectionChangedListener() {

			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				Movie movie = (Movie) ((StructuredSelection) event
						.getSelection()).getFirstElement();
				if (movie == null)
					return;

				moviePartListener.selected(movie);
			}
		});
	}

	public void add(Movie movie) {
		list.add(movie);
		list.setSelection(new StructuredSelection(movie));
	}

	public void delete(Movie movie) {
		list.remove(movie);
	}

	public void setValue(List<Movie> movies) {
		list.setInput(movies);
	}

	public void setSelectionListener(IMoviePartListener listener) {
		this.moviePartListener = listener;
	}

	public Movie getSelection() {
		return (Movie) ((StructuredSelection) list.getSelection())
				.getFirstElement();
	}
}
